#include <stdio.h>

#include "pile.h"

#include "probleme.h"


int main (int argc, char *argv[]) {
  Probleme *problemePose;
  
  Etat *etatInit, *etatCourant,*e;

  Pile *pilePrincipale, *pileAuxiliaire;

#ifndef _UNE_SOLUTION_

  int nbSolutions= 0;

  
#endif


  char infos[80];
  int continueComputing =1;
  if (argc ==2 ) {
    problemePose=initProbleme(argv[1]);
    if ( problemePose== NULL) {
      fprintf(stderr, "Probleme invalide %s\n", argv[1]);
      exit(1);
    }
  }
    else {
      fprintf(stderr, "Appel Obligatoire \n\n %s   nomFichierDEDescriptionDuProbleme \n", argv[0]);
      exit(1);
    
  }

  pilePrincipale= nouvellePile();
  pileAuxiliaire= nouvellePile();
  
  etatInit = premierEtat(problemePose,argv[1]);
  while (continueComputing == 1)    {
    while(preSolve(etatInit) !=0);
     if (preSolve2(etatInit) == 0)
         continueComputing = 0;
  }

  imprimerEtat(problemePose,etatInit);
  empiler(pilePrincipale, etatInit);


  while( ! pileVide(pilePrincipale)) {
    etatCourant=depiler(pilePrincipale);
    if(estSolution(problemePose, etatCourant)==1) {
	 imprimerEtat(problemePose, etatCourant) ;
	 libererEtat(etatCourant);
#ifdef  _UNE_SOLUTION_ 
	 break;
#else 
	 nbSolutions++;
	 continue;
#endif
    }
    e=etatCourant;
    if ( ! estEchec(problemePose, etatCourant) ){
      etatCourant=etatSuivant(problemePose, etatCourant);
      while ( etatCourant  != NULL){
	empiler(pileAuxiliaire, etatCourant);
	etatCourant=etatSuivant(problemePose, NULL);
      }
      while(! pileVide(pileAuxiliaire) ) {
	etatCourant = depiler(pileAuxiliaire);
	empiler(pilePrincipale, etatCourant);
      }
    }
    libererEtat(e);
  }
 
  
#ifdef _UNE_SOLUTION_ 
  sprintf(infos, "Hauteur maximale de la pile, %d\n ", hauteurMax(pilePrincipale));
#else
  sprintf(infos, "Hauteur maximale de la pile, %d\n Nombre de solutions %d \n ", 
	 hauteurMax(pilePrincipale),nbSolutions);
#endif
  libererPile(pilePrincipale);
  libererPile(pileAuxiliaire);
  terminerProbleme(problemePose, 1, infos); 
  return 0; 
 
  }
